package com.computergames.server.service.Implement;

import com.computergames.server.message.AbstractGameMessage;
import com.computergames.server.message.chessMessage.AbstractChessMessage;
import com.computergames.server.server.session.RoomSessionFactory;
import com.computergames.server.server.session.RoomSessionService;
import com.computergames.server.service.Interface.GameStorage;
import com.computergames.server.util.RedisUtil;
import com.computergames.server.util.SpringUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.AttributeKey;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class GobangStorage implements GameStorage {
    private static final GobangStorage INSTANCE = new GobangStorage();

    private GobangStorage()
    {
    }

    public static GobangStorage getInstance()
    {
        return INSTANCE;
    }

    // 一个房间对应一个棋谱
    private final Map<String, List<String>> gobangStorageMap = new ConcurrentHashMap<>();
    @Override
    public void save(String roomName, AbstractGameMessage content, int result, ChannelHandlerContext ctx) {
        AbstractChessMessage chessContent = (AbstractChessMessage) content;
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);
        String[] coordinate = chessContent.getCoordinate(); //eg:A3
        String player = chessContent.getChess(); //eg:hei
        RoomSessionService roomSessionService = RoomSessionFactory.getRoomSession();
        List<Channel> channels = roomSessionService.getMembersChannel(roomName);

        // 确保坐标字符串不为空且格式正确
        if (coordinate != null && coordinate.length == 1 && coordinate[0].length() == 2
                && Character.isLetter(coordinate[0].charAt(0))
                && Character.isDigit(coordinate[0].charAt(1))) {

            // 分离X坐标（字母）和Y坐标（数字）
            String x = String.valueOf(coordinate[0].charAt(0)); // A, C等
            int y = Integer.parseInt(coordinate[0].substring(1)); // 5, 6等

            // 检查房间是否存在，不存在则初始化
            gobangStorageMap.computeIfAbsent(roomName, k -> new ArrayList<>());

            // 根据玩家类型构建棋谱记录
            String record;
            if ("hei".equals(player)) {
                record = "B(" + x + "," + y + ")";
            } else if ("bai".equals(player)) {
                record = "W(" + x + "," + y + ")";
            } else {
                throw new IllegalArgumentException("Invalid player type: " + player);
            }

            // 将记录添加到房间对应的棋谱列表中
            gobangStorageMap.get(roomName).add(record);

            if(result == 1){
                //保存棋谱
                Map<String, Object> recordsData = new ConcurrentHashMap<>();
                List<String> records = gobangStorageMap.get(roomName);
                recordsData.put(roomName, records);
                redisUtil.hmset(roomName + "棋谱", recordsData);
                //保存积分
                String stage = (String)ctx.channel().attr(AttributeKey.valueOf("USER_STAGE")).get();
                for(Channel channel : channels){
                    String username = (String)channel.attr(AttributeKey.valueOf("USER_IDENTIFIER")).get();
                    if(channel.equals(ctx.channel())){
                        redisUtil.hincr(roomName + stage + "积分", username, 2);
                    }else{
                        redisUtil.hincr(roomName + stage + "积分", username, 0);
                    }
                }
                gobangStorageMap.remove(roomName);
                recordsData.remove(roomName);
            } else if(result == 2){
                //保存棋谱
                Map<String, Object> recordsData = new ConcurrentHashMap<>();
                List<String> records = gobangStorageMap.get(roomName);
                recordsData.put(roomName, records);
                redisUtil.hmset(roomName + "棋谱", recordsData);
                //保存积分
                String stage = (String)ctx.channel().attr(AttributeKey.valueOf("USER_STAGE")).get();
                for(Channel channel : channels){
                    String username = (String)channel.attr(AttributeKey.valueOf("USER_IDENTIFIER")).get();
                    redisUtil.hincr(roomName + stage + "积分", username, 1);
                }
                gobangStorageMap.remove(roomName);
                recordsData.remove(roomName);
            }
        }
    }

    @Override
    public List<String> getValuesForKey(String key) {
        return gobangStorageMap.get(key);
    }

}
